package gps.states;

import gps.Colors;
import gps.Direction;

/**
 * 
 * Esta clase define el estado de una celda.
 * c_i = (D, color1, color2)
 * donde
 * 		D: Direccion (NONE para cuadrado blanco o negro, VERTICAL para los mitad y mitad verticales, HORIZONTAL para los mitad y mitad horizontales.
 * 		firstColor: BLACK o WHITE de acuerdo a si la mitad izquierda o superior son negras o blancas respectivamente
 * 		sndColor: BLACK o WHITE de acuerdo a si la mitad derecha o inferior son negras o blancas respectivamente
 * En caso que l cuadrado sea todo blanco o negro ----> color1 = color2		
 * 
 * @author grupo 2
 *
 */
public class SquareState {
	private Direction direction;
	private Colors firstColor;
	private Colors sndColor;
	
	public static SquareState rotate90(SquareState orgState){
		if(orgState == null)
			return null;
		
		if(orgState.isUniform()){
			return orgState;
		}

		Direction dir;
		Colors fst;
		Colors snd;
		
		if(orgState.direction == Direction.HORIZONTAL){
			dir = Direction.VERTICAL;
			fst = orgState.sndColor;
			snd = orgState.firstColor;
		} else {
			dir = Direction.HORIZONTAL;
			fst = orgState.firstColor;
			snd = orgState.sndColor;
		}
		
		return new SquareState(dir, fst, snd);
	}
	
	public static SquareState mirror(Direction dir, SquareState orgState){
		if(orgState == null || orgState.isUniform() || orgState.direction != dir)
			return orgState;
		
			return new SquareState(orgState.sndColor, orgState.firstColor);
	}
	
	
	public static boolean areEquals(SquareState[] st1, SquareState[] st2){
		if(st1 == null || st2 == null || st1.length != st2.length){
			return false;
		}
		
		for(int i=0 ; i< st1.length ; i++){
			if(!st1[i].equals(st2[i])){
				return false;
			}
		}
		return true;
		
	}
	
	public SquareState (Direction direction, Colors firstColor, Colors sndColor) {
		this.direction = direction;
		this.firstColor = firstColor;
		this.sndColor = sndColor;
	}
	
	public SquareState (Colors firstColor, Colors sndColor) {
		this(Direction.NONE, firstColor, sndColor);
	}
	
	public void setDirection (Direction direction) {
		this.direction = direction;
	}
	
	public void setFirstColor (Colors firstColor) {
		this.firstColor = firstColor;
	}
	
	public void setSndColor (Colors sndColor) {
		this.sndColor = sndColor;
	}
	
	public Direction getDirection () {
		return this.direction;
	}
	
	public Colors getFirstColor () {
		return this.firstColor;
	}
	
	public Colors getSndColor () {
		return this.sndColor;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((direction == null) ? 0 : direction.hashCode());
		result = prime * result
				+ ((firstColor == null) ? 0 : firstColor.hashCode());
		result = prime * result
				+ ((sndColor == null) ? 0 : sndColor.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object object) {
		if (this == object) {
			return true;
		}
		if (!(object instanceof SquareState)) {
			return false;
		}
		SquareState squareState = (SquareState) object;
		return (this.direction.equals(squareState.direction) && this.firstColor.equals(squareState.firstColor) 
				&& this.sndColor.equals(squareState.sndColor)); 
	}
	
	@Override
	public String toString() {
		return "(" + this.direction + ", " + this.firstColor + ", " + this.sndColor + ")";
	}
	
	public boolean isUniform(){
		return direction == Direction.NONE;
	}
}
